package com.suning.framework.utils;

import com.suning.framework.es.EsBasePojo;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.PropertyFilter;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 16080951(林健)
 * @Copyright (c) 2016 苏宁软件技术有限公司 版权所有
 * @see [相关类/方法]（可选）
 * @since [产品 /模块版本] （可选）
 */
public class JsonUtils {

    /**
     * 从一个JSON 对象字符格式中得到一个java对象
     *
     * @param <T>        the type parameter
     * @param jsonString the json string
     * @param beanCalss  the bean calss
     * @return t
     */
    @SuppressWarnings("unchecked")
    public static <T> T jsonToBean(String jsonString, Class<T> beanCalss) {

        JSONObject jsonObject = JSONObject.fromObject(jsonString);
        T bean = (T) JSONObject.toBean(jsonObject, beanCalss);

        return bean;

    }

    /**
     * 将java对象转换成json字符串
     *
     * @param bean the bean
     * @return string
     */
    public static String beanToJson(Object bean) {

        JSONObject json = JSONObject.fromObject(bean);

        return json.toString();

    }

    /**
     * 将java对象转换成json字符串
     *
     * @param bean          the bean
     * @param _nory_changes the nory changes
     * @param nory          the nory
     * @return string
     */
    public static String beanToJson(Object bean, String[] _nory_changes, boolean nory) {

        JSONObject json = null;

        if(nory){//转换_nory_changes里的属性

            Field[] fields = bean.getClass().getDeclaredFields();
            String str = "";
            for(Field field : fields){
                //              System.out.println(field.getName());
                str+=(":"+field.getName());
            }
            fields = bean.getClass().getSuperclass().getDeclaredFields();
            for(Field field : fields){
                //              System.out.println(field.getName());
                str+=(":"+field.getName());
            }
            str+=":";
            for(String s : _nory_changes){
                str = str.replace(":"+s+":", ":");
            }
            json = JSONObject.fromObject(bean,configJson(str.split(":")));

        }else{//转换除了_nory_changes里的属性



            json = JSONObject.fromObject(bean,configJson(_nory_changes));
        }



        return json.toString();

    }

    /**
     * 排除指定的属性,并将有null或者为空的去除。
     *
     * @param <T>      the type parameter
     * @param clazz    the clazz
     * @param exclouds the exclouds
     * @return json object
     */
    public static <T extends EsBasePojo> JSONObject excloudsCustomProperty(T clazz, final String[] exclouds){
        JsonConfig jsonConfig = formatJsonDate("yyyy-MM-dd");
        jsonConfig.setJsonPropertyFilter(new PropertyFilter() {
            @Override
            public boolean apply(Object o, String s, Object o1) {
                for(String params : exclouds){
                    if(params.equals(s)) return true;
                }

                if(o1 == null || "".equals(o1)) return true;
                return false;
            }
        });

        return JSONObject.fromObject(clazz,jsonConfig);
    }


    /**
     * 对时间进行格式化。
     *
     * @param timeFormate the json object
     * @return json object
     */
    public static JsonConfig formatJsonDate(String timeFormate) {
        JsonConfig config = new JsonConfig();
        //对时间进行自定义
        config.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor(timeFormate));
        return config;
    }

    /**
     * 排除指定的属性,并将有null或者为空的去除，并对时间进行格式化。
     *
     * @param jsonObject the json object
     * @return json object
     */
    public static JSONObject formatJson(JSONObject jsonObject){
        JsonConfig config = new JsonConfig();
        //对时间进行自定义
        config.registerJsonValueProcessor(Date.class,new JsonDateValueProcessor("yyyy-MM-dd"));
        //对有空的，null的，不要参与序列化
        config.setJsonPropertyFilter(new PropertyFilter() {
            @Override
            public boolean apply(Object o, String s, Object o1) {
                return o1 == null || "".equals(o1);
            }
        });

        return JSONObject.fromObject(jsonObject, config);
    }

    private static JsonConfig configJson(String[] excludes) {

        JsonConfig jsonConfig = new JsonConfig();

        jsonConfig.setExcludes(excludes);
        //
        jsonConfig.setIgnoreDefaultExcludes(false);
        //
        //              jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);

        //              jsonConfig.registerJsonValueProcessor(Date.class,
        //
        //                  new DateJsonValueProcessor(datePattern));



        return jsonConfig;

    }

    /**
     * 将java对象List集合转换成json字符串
     *
     * @param beans the beans
     * @return string
     */
    @SuppressWarnings("unchecked")
    public static String beanListToJson(List beans) {

        StringBuffer rest = new StringBuffer();

        rest.append("[");

        int size = beans.size();

        for (int i = 0; i < size; i++) {

            rest.append(beanToJson(beans.get(i))+((i<size-1)?",":""));

        }

        rest.append("]");

        return rest.toString();

    }

    /**
     * Bean list to json string.
     *
     * @param beans         the beans
     * @param _nory_changes the nory changes
     * @param nory          the nory
     * @return string
     */
    @SuppressWarnings("unchecked")
    public static String beanListToJson(List beans, String[] _nory_changes, boolean nory) {

        StringBuffer rest = new StringBuffer();

        rest.append("[");

        int size = beans.size();

        for (int i = 0; i < size; i++) {
            try{
                rest.append(beanToJson(beans.get(i),_nory_changes,nory));
                if(i<size-1){
                    rest.append(",");
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }

        rest.append("]");

        return rest.toString();

    }

    /**
     * 从json HASH表达式中获取一个map，改map支持嵌套功能
     *
     * @param jsonString the json string
     * @return map
     */
    @SuppressWarnings({ "unchecked" })
    public static Map jsonToMap(String jsonString) {

        JSONObject jsonObject = JSONObject.fromObject(jsonString);
        Iterator keyIter = jsonObject.keys();
        String key;
        Object value;
        Map valueMap = new HashMap();

        while (keyIter.hasNext()) {

            key = (String) keyIter.next();
            value = jsonObject.get(key).toString();
            valueMap.put(key, value);

        }

        return valueMap;
    }

    /**
     * map集合转换成json格式数据
     *
     * @param map           the map
     * @param _nory_changes the nory changes
     * @param nory          the nory
     * @return string
     */
    public static String mapToJson(Map<String, ?> map, String[] _nory_changes, boolean nory){

        String s_json = "{";

        Set<String> key = map.keySet();
        for (Iterator<?> it = key.iterator(); it.hasNext();) {
            String s = (String) it.next();
            if(map.get(s) == null){

            }else if(map.get(s) instanceof List<?>){
                s_json+=(s+":"+beanListToJson((List<?>)map.get(s), _nory_changes, nory));

            }else{
                JSONObject json = JSONObject.fromObject(map);
                s_json += (s+":"+json.toString());;
            }

            if(it.hasNext()){
                s_json+=",";
            }
        }

        s_json+="}";
        return s_json;
    }

    /**
     * 从json数组中得到相应java数组
     *
     * @param jsonString the json string
     * @return object [ ]
     */
    public static Object[] jsonToObjectArray(String jsonString) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);

        return jsonArray.toArray();

    }

    /**
     * List to json string.
     *
     * @param list the list
     * @return the string
     */
    public static String listToJson(List<?> list) {

        JSONArray jsonArray = JSONArray.fromObject(list);

        return jsonArray.toString();

    }

    /**
     * 从json对象集合表达式中得到一个java对象列表
     *
     * @param <T>        the type parameter
     * @param jsonString the json string
     * @param beanClass  the bean class
     * @return list
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> jsonToBeanList(String jsonString, Class<T> beanClass) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        JSONObject jsonObject;
        T bean;
        int size = jsonArray.size();
        List<T> list = new ArrayList<T>(size);

        for (int i = 0; i < size; i++) {

            jsonObject = jsonArray.getJSONObject(i);
            bean = (T) JSONObject.toBean(jsonObject, beanClass);
            list.add(bean);

        }

        return list;

    }

    /**
     * 从json数组中解析出java字符串数组
     *
     * @param jsonString the json string
     * @return string [ ]
     */
    public static String[] jsonToStringArray(String jsonString) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        String[] stringArray = new String[jsonArray.size()];
        int size = jsonArray.size();

        for (int i = 0; i < size; i++) {

            stringArray[i] = jsonArray.getString(i);

        }

        return stringArray;
    }

    /**
     * 从json数组中解析出javaLong型对象数组
     *
     * @param jsonString the json string
     * @return long [ ]
     */
    public static Long[] jsonToLongArray(String jsonString) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        int size = jsonArray.size();
        Long[] longArray = new Long[size];

        for (int i = 0; i < size; i++) {

            longArray[i] = jsonArray.getLong(i);

        }

        return longArray;

    }

    /**
     * 从json数组中解析出java Integer型对象数组
     *
     * @param jsonString the json string
     * @return integer [ ]
     */
    public static Integer[] jsonToIntegerArray(String jsonString) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        int size = jsonArray.size();
        Integer[] integerArray = new Integer[size];

        for (int i = 0; i < size; i++) {

            integerArray[i] = jsonArray.getInt(i);

        }

        return integerArray;

    }

    /**
     * 从json数组中解析出java Double型对象数组
     *
     * @param jsonString the json string
     * @return double [ ]
     */
    public static Double[] jsonToDoubleArray(String jsonString) {

        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        int size = jsonArray.size();
        Double[] doubleArray = new Double[size];

        for (int i = 0; i < size; i++) {

            doubleArray[i] = jsonArray.getDouble(i);

        }

        return doubleArray;

    }
}
